#include "BondCSIPriceInfo.h"

#define CSI_PRECISION 1E-5

CBondCSInfo::CBondCSInfo() {}

CBondCSInfo::~CBondCSInfo() {}

CBondCSInfo& CBondCSInfo::instance() {
  static CBondCSInfo s_bcs;
  return s_bcs;
}

void CBondCSInfo::clear() {
  SCOPED_LOCK(GetMutex());

  m_umapCsi.clear();
}

void CBondCSInfo::add(const xCSIList_c* plist) {
  char keybuf[64] = {0};
  SCOPED_LOCK(GetMutex());
  for (std::list<xCSIUint_c>::const_iterator itr = plist->m_List.begin();
       itr != plist->m_List.end(); ++itr) {
    const xCSIUint_c& csiu = *itr;

    if (csiu.m_bond_key[0] == '\0' || csiu.m_listedmarket[0] == '\0') continue;

    // FMTBUF(keybuf, "%s.%s", csiu.m_bond_key, csiu.m_listedmarket);
    // m_umapCsi[keybuf] = csiu;
    m_umapCsi.insert({std::string(csiu.m_bond_key) + std::string(".") +
                          std::string(csiu.m_listedmarket),
                      csiu});
  }
}

std::string CBondCSInfo::BuildCombondkey(const std::string& sBondKey,
                                         const std::string& sLisMakert) {
  return sBondKey + std::string(".") + sLisMakert;
}
static_assert(sizeof(xCSIUint_c) == 120, "");
UINT CBondCSInfo::GetBondCsiDate(const std::string& sCombondkey) {
  static UINT date_invalid = 0;

  {
    qb::base::TempTinyString key(sCombondkey);
    SCOPED_LOCK(GetMutex());
    auto itrFind = m_umapCsi.find(key);

    return itrFind == m_umapCsi.end() ? date_invalid : itrFind->second.m_nDate;
  }
}

bool CBondCSInfo::GetCsiUnit(const std::string& sCombondkey,
                             xCSIUint_c& xUnit) {
  xUnit.clear();
  qb::base::TempTinyString key(sCombondkey);
  SCOPED_LOCK(GetMutex());
  auto itrFind = m_umapCsi.find(key);
  if (itrFind != m_umapCsi.end()) {
    itrFind->second.GetCSIU(xUnit);
    // xUnit里面的m_bond_key,m_listedmarket无需拷贝,外面不会使用
  }

  return itrFind != m_umapCsi.end();
}

double CBondCSInfo::GetCsiYieldForSort(const std::string& sCombondkey) {
  qb::base::TempTinyString key(sCombondkey);
  SCOPED_LOCK(GetMutex());
  auto itrFind = m_umapCsi.find(key);
  if (itrFind != m_umapCsi.end()) {
    const auto& xUnit = itrFind->second;
    return xUnit.m_dYieldToExercise > _INVALID_CSI_VALUE
               ? xUnit.m_dYieldToExercise
               : xUnit.m_dYieldToMaturity;
  }

  return _INVALID_CSI_VALUE;
}

double CBondCSInfo::GetCsiCleanPriceForSort(const std::string& sCombondkey) {
  qb::base::TempTinyString key(sCombondkey);
  SCOPED_LOCK(GetMutex());
  auto itrFind = m_umapCsi.find(key);
  if (itrFind != m_umapCsi.end()) {
    const auto& xUnit = itrFind->second;
    return xUnit.m_dCleanPriceExercise > _INVALID_CSI_VALUE
               ? xUnit.m_dCleanPriceExercise
               : xUnit.m_dCleanPriceMaturity;
  }

  return _INVALID_CSI_VALUE;
}

double CBondCSInfo::GetCsiFullPriceForSort(const std::string& sCombondkey) {
  SCOPED_LOCK(GetMutex());
  auto itrFind = m_umapCsi.find(sCombondkey);
  if (itrFind != m_umapCsi.end()) {
    const auto& xUnit = itrFind->second;
    return xUnit.m_dFullPriceExercise > _INVALID_CSI_VALUE
               ? xUnit.m_dFullPriceExercise
               : xUnit.m_dFullPriceMaturity;
  }

  return _INVALID_CSI_VALUE;
}
